﻿/// Author: Petr Pechovic
/// Contact: http://www.pechovic.eu
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;
using System.Web.UI.WebControls;
using DotNetSources.Web.UI.Buttons.CssModel;
using DotNetSources.Web.UI.Buttons.Popup;
using DotNetSources.Web.UI.Buttons.Interfaces;

[assembly: WebResource("DotNetSources.Web.UI.Buttons.Popup.BoxBase.js", "text/javascript", PerformSubstitution = true)]
[assembly: WebResource("DotNetSources.Web.UI.Buttons.Popup.BoxBase.css", "text/css")]

namespace DotNetSources.Web.UI.Buttons {

    /// <summary>
    /// Base box taking care of design and base settings of boxes. You have to derive and specify the buttons.
    /// </summary>
    [Css("DotNetSources.Web.UI.Buttons.Popup.BoxBase.css")]
    public abstract class BoxBase : ScriptWebControl, IBox, INamingContainer {

        #region Ctor.

        /// <summary>
        /// This will be div.
        /// </summary>
        public BoxBase()
            : base(HtmlTextWriterTag.Div) {
        }

        #endregion

        #region Controls

        /// <summary>
        /// Keep this for handover ID to JavaScript.
        /// </summary>
        protected Image imgIcon;

        /// <summary>
        /// Keep this for handover ID to JavaScript.
        /// </summary>
        protected Panel pnlMessage;

        /// <summary>
        /// Keep this to set right javascript close action in OnPreRender.
        /// </summary>
        private ImageButton closeBtn;

        #endregion

        #region Properties

        /// <summary>
        /// Specify if the box will have shadow.
        /// </summary>
        public bool DropShadow {
            get {
                object obj = this.ViewState["DropShadow"];
                if (obj != null) {
                    return (bool)obj;
                }
                return true;
            }
            set {
                this.ViewState["DropShadow"] = value;
            }

        }

        /// <summary>
        /// Icon ID for changing icon on client side.
        /// </summary>
        public string IconId {
            get {
                return Helper.GetJSId(imgIcon);
            }
        }

        /// <summary>
        /// Message ID for changing message in box.
        /// </summary>
        public string MessageId {
            get {
                return Helper.GetJSId(pnlMessage);
            }
        }

        #endregion

        #region Variables

        /// <summary>
        /// Message. Set only if the show on server side is called.
        /// </summary>
        private string message = string.Empty;

        /// <summary>
        /// Icon.
        ///</summary>
        private Icon icon = Icon.Undefined;

        #endregion

        protected override void OnInit(EventArgs e) {

            // build header
            Controls.Add(BuildHeader());

            // build body
            Controls.Add(BuildBody());

            // build footer
            Controls.Add(BuildFooter());

            base.OnInit(e);
        }

        protected override void OnPreRender(EventArgs e) {

            // set styles
            SetCssStyles();

            // set close button script
            closeBtn.OnClientClick = GetCloseButtonClickScript();

            // display box if wanted
            if (icon != Icon.Undefined) {
                string js = string.Format(
                    ";(function() {{" +
                        "var __f = function() {{" +
                            "$find('{2}').Show('{0}', DotNetSources.Icons.{1}); " +
                            "Sys.Application.remove_load(__f);" +
                        "}};" +
                        "Sys.Application.add_load(__f);" +
                    "}})();",
                    message, 
                    icon.ToString(),
                    Helper.GetJSId(this));

                ScriptManager.RegisterStartupScript(this,
                    this.GetType(),
                    "Show" + UniqueID,
                    js,
                    true);
            }

            base.OnPreRender(e);
        }

        /// <summary>
        /// Build header DIV which are title and close button.
        /// </summary>
        /// <returns></returns>
        private Panel BuildHeader() {
            // header container
            Panel header = new Panel();
            header.CssClass = "dns_box_header";

            // title
            Panel title = new Panel();
            title.CssClass = "dns_box_heder_title";
            header.Controls.Add(title);

            // close button
            Panel close = new Panel();
            close.CssClass = "dns_box_header_close";
            closeBtn = new DotNetSources.Web.UI.Buttons.ImageButton();
            // set image from resources
            closeBtn.ImageUrl = Page.ClientScript.GetWebResourceUrl(closeBtn.GetType(), "DotNetSources.Web.UI.Buttons.Icons.close.jpg");
            close.Controls.Add(closeBtn);
            header.Controls.Add(close);

            return header;
        }

        /// <summary>
        /// Build body which are icon and message.
        /// </summary>
        /// <returns></returns>
        private Panel BuildBody() {

            Panel body = new Panel();
            body.CssClass = "dns_box_body";

            Panel pnlIcon = new Panel();
            pnlIcon.ID = "iconPanel";
            pnlIcon.CssClass = "dns_box_icon";
            body.Controls.Add(pnlIcon);

            // Icon image
            imgIcon = new Image();
            imgIcon.ID = "imgIcon";
            pnlIcon.Controls.Add(imgIcon);

            pnlMessage = new Panel();
            pnlMessage.ID = "messagePanel";
            pnlMessage.CssClass = "dns_box_message";
            body.Controls.Add(pnlMessage);

            body.Controls.Add(new ClearDiv());

            return body;
        }

        /// <summary>
        /// Build footer which are buttons.
        /// </summary>
        /// <returns></returns>
        private Panel BuildFooter() {

            // buttons
            Panel footer = new Panel();
            footer.CssClass = "dns_box_footer";
            footer.Controls.Add(GetPanelWithButtons());

            // bottom
            Panel bottom = new Panel();
            bottom.CssClass = "dns_box_bottom";
            footer.Controls.Add(bottom);

            return footer;
        }

        /// <summary>
        /// Public interface for displaying box from server side.
        /// </summary>
        /// <param name="message"></param>
        /// <param name="icon"></param>
        public void Show(string message, Icon icon) {
            this.message = message;
            this.icon = icon;
        }

        /// <summary>
        /// Localization of buttons.
        /// </summary>
        /// <param name="args"></param>
        public abstract void Localize(params string[] args);

        protected virtual void SetCssStyles() {
            CssClass = "dns_box_main";
            if (DropShadow)
                CssClass += " dns_drop_shadow";
        }

        /// <summary>
        /// The script for closing box can be different in message box and in confirm box. 
        /// So lets it specify in concrete implementation.
        /// </summary>
        /// <returns></returns>
        protected virtual string GetCloseButtonClickScript() {
            return string.Format("javascript: $find('{0}').Hide(); return false;", Helper.GetJSId(this));
        }

        /// <summary>
        /// Get panel with custom buttons specyfied in concrete class.
        /// </summary>
        /// <returns></returns>
        protected abstract Panel GetPanelWithButtons();

        public override IEnumerable<System.Web.UI.ScriptDescriptor> GetScriptDescriptors() {
            ScriptControlDescriptor descriptor = new ScriptControlDescriptor("DotNetSources.BoxBase", this.ClientID);
            descriptor.AddProperty("iconId", IconId);
            descriptor.AddProperty("messageId", MessageId);
            descriptor.AddProperty("backgroundId", Helper.RetypeToBoxContextPage(Page).BackgroundId);
            return new ScriptControlDescriptor[] { descriptor };
        }

        public override IEnumerable<System.Web.UI.ScriptReference> GetScriptReferences() {
            ScriptReference jsReference = new ScriptReference();
            jsReference.Assembly = "DotNetSources.Web.UI.Buttons";
            jsReference.Name = "DotNetSources.Web.UI.Buttons.Popup.BoxBase.js";
            return new ScriptReference[] { jsReference };
        }

    }

}

